﻿using SL651Center2.x.Enums;
using SL651Center2.x.Messages;
using System.Text;

namespace SL651Center2.x.Send
{
    public class BuildResponse
    {
        /// <summary>
        /// 创建响应报文
        /// </summary>
        /// <param name="messageFrame">报头</param>
        /// <param name="serialnum">流水号字节数组</param>
        /// <param name="endMarks">结束符</param>
        /// <returns>响应报文字节数组</returns>
        public static byte[] CreatResponse(MessageFrame messageFrame, byte[] serialnum, EndMarks endMarks)
        {
            if (messageFrame.FrameCode == FrameCode.ASCII)
            {
                return CreatResponseASCII(messageFrame, serialnum, endMarks);
            }
            List<byte> data = new List<byte>();
            //添加帧起始符
            data.AddRange(messageFrame.FrameCoding);
            //遥测站地址
            data.AddRange(messageFrame.TelemetryAddress);
            //中心站地址
            data.AddRange(messageFrame.CentralAddress);
            //密码
            data.AddRange(messageFrame.PassWord);
            //功能码
            data.Add((byte)messageFrame.FunctionCode);

            //上下行表示和报文长度
            string len = Convert.ToString(8, 2).PadLeft(12, '0');
            string ln = $"1000{len}";
            var hexlen = string.Format("{0:X2}", Convert.ToInt16(ln, 2));
            var bl = Helper.HEXStrToByte(hexlen);
            data.AddRange(bl);

            //报文起始符
            data.Add((byte)messageFrame.StartMark);

            //如果是多包传输则添加包总数和序列号
            if (messageFrame.Package.Any())
            {
                data.AddRange(messageFrame.Package);
            }

            //流水号
            data.AddRange(serialnum);

            //获取当前时间
            byte[] time = Helper.GetBCDTimeBytes();
            //添加发报时间
            data.AddRange(time);

            //结束符
            data.Add((byte)endMarks);

            //校验码
            var crc = Helper.Crc16(data.ToArray());
            data.AddRange(crc);


            return data.ToArray();
        }

        /// <summary>
        /// 创建ASCII格式的响应报文
        /// </summary>
        /// <param name="messageFrame">报头</param>
        /// <param name="serialnum">流水号字节数组</param>
        /// <param name="endMarks">结束符</param>
        /// <returns>响应报文字节数组</returns>
        static byte[] CreatResponseASCII(MessageFrame messageFrame, byte[] serialnum, EndMarks endMarks)
        {
            List<byte> data = new List<byte>();
            //添加帧起始符
            data.AddRange(messageFrame.FrameCoding);
            //遥测站地址
            data.AddRange(messageFrame.TelemetryAddress);
            //中心站地址
            data.AddRange(messageFrame.CentralAddress);
            //密码
            data.AddRange(messageFrame.PassWord);
            //功能码
            var fh = Helper.ToHEXString((byte)messageFrame.FunctionCode);
            var ah = Encoding.ASCII.GetBytes(fh);
            data.AddRange(ah);

            //上下行表示和报文长度
            string len = Convert.ToString(16, 2).PadLeft(12, '0');
            string ln = $"1000{len}";
            var hexlen = string.Format("{0:X2}", Convert.ToInt16(ln, 2));
            var bl = Encoding.ASCII.GetBytes(hexlen);
            data.AddRange(bl);

            //报文起始符
            data.Add((byte)messageFrame.StartMark);

            //如果是多包传输则添加包总数和序列号
            if (messageFrame.Package.Any())
            {
                data.AddRange(messageFrame.Package);
            }

            //流水号
            data.AddRange(serialnum);

            //获取当前时间
            byte[] time = Helper.GetBCDTimeBytes(false);
            //添加发报时间
            data.AddRange(time);

            //结束符
            data.Add((byte)endMarks);

            //校验码
            var crc = Helper.Crc16(data.ToArray());
            var ch = Helper.ToHEXString(crc);
            var cb = Encoding.ASCII.GetBytes(ch);
            data.AddRange(cb);

            return data.ToArray();
        }

        /// <summary>
        /// 创建响应报文
        /// </summary>
        /// <param name="messageFrame">报头</param>
        /// <param name="serialnum">流水号</param>
        /// <param name="endMarks">结束符</param>
        /// <returns>响应报文字节数组</returns>
        public static byte[] CreatResponse(MessageFrame messageFrame, ushort serialnum, EndMarks endMarks)
        {
            if (messageFrame.FrameCode==FrameCode.ASCII)
            {
                var hs = string.Format("{0:X2}", serialnum).PadLeft(4, '0');
                var bs = Encoding.ASCII.GetBytes(hs);
                return CreatResponseASCII(messageFrame, bs, endMarks);
            }
            else
            {
                var hs = string.Format("{0:X2}", serialnum).PadLeft(4, '0');
                var bs = Helper.HEXStrToByte(hs);
                return CreatResponse(messageFrame, bs, endMarks);
            }
        }



    }

}
